//
// Created by Zsir on 2025/7/29.
//

#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cstring>
#include <cstdio>
#include <fcntl.h>
#include <cerrno>
#include <iostream>
#include "TcpServer.h"
#include "sys/epoll.h"
#include "poll.h"

struct conn *conn_list;

TcpServer::TcpServer(int port, int maxPort) :
    port_(port),
    maxPort_(maxPort)
{
    sockfds_ = (int *) malloc(maxPort * sizeof(int));
    epfd_ = epoll_create(1);
    conn_list = (struct conn *) malloc(65536 * sizeof(struct conn)); // 为更多连接分配空间
    for (int i = 0; i < maxPort; i++)
    {
        sockfds_[i] = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfds_[i] < 0)
        {
            perror("socket");
            return;
        }

        memset(&addr_, 0, sizeof(sockaddr_in));
        addr_.sin_family = AF_INET;
        addr_.sin_port = htons(port_ + i);
        addr_.sin_addr.s_addr = INADDR_ANY;

        conn_list[sockfds_[i]].fd = sockfds_[i];
        conn_list[sockfds_[i]].r_action.recv_callback = std::bind(&TcpServer::accept_cb, this, std::placeholders::_1);
        //先设置好监听事件套接字
        set_event(sockfds_[i], EPOLLIN, 1);
    }
}

TcpServer::~TcpServer()
{
    if (sockfds_ != nullptr)
    {
        for (int i = 0; i < maxPort_; i++)
        {
            if (sockfds_[i] >= 0)
            {
                close(sockfds_[i]);
            }
        }
        free(sockfds_);
        sockfds_ = nullptr;
    }
    if (epfd_ >= 0)
    {
        close(epfd_);
    }
}

int TcpServer::bind()
{
    for (int i = 0; i < maxPort_; i++)
    {
        struct sockaddr_in addr;
        memset(&addr, 0, sizeof(sockaddr_in));
        addr.sin_family = AF_INET;
        addr.sin_port = htons(port_ + i);
        addr.sin_addr.s_addr = INADDR_ANY;

        int ret = ::bind(sockfds_[i], (struct sockaddr *) &addr, sizeof(struct sockaddr_in));
        if (ret < 0)
        {
            perror("bind");
        }
    }
    return 1;
}

int TcpServer::listen()
{
    for (int i = 0; i < maxPort_; i++)
    {
        if (::listen(sockfds_[i], 10) < 0)
        {
            perror("listen");
        }
    }
    return 1;
}

int TcpServer::accept()
{
    printf("Server started, waiting for connections on port %d...\n", port_);

    while (1)
    {
        struct sockaddr_in clientaddr{};
        memset(&clientaddr, 0, sizeof(sockaddr_in));
        socklen_t clientlen = sizeof(clientaddr);
        int clientfd = ::accept(sockfds_[0], (struct sockaddr *) &clientaddr, &clientlen);  // 修复：使用第一个监听socket

        if (clientfd < 0)
        {
            perror("accept");
            continue;
        }

        char client_ip[INET_ADDRSTRLEN];
        inet_ntop(AF_INET, &clientaddr.sin_addr, client_ip, INET_ADDRSTRLEN);
        printf("New connection from %s:%d\n", client_ip, ntohs(clientaddr.sin_port));

        Thread *thread = new Thread(clientFunc, reinterpret_cast<void *>(clientfd));
    }
}

void *TcpServer::clientFunc(void *arg)
{
    int clientfd = static_cast<int>(reinterpret_cast<intptr_t>(arg));

    while (1)
    {
        char buffer[1024];
        ssize_t len = recv(clientfd, buffer, sizeof(buffer), 0);
        if (len <= 0)
        {
            if (len < 0)
            {
                perror("recv error");
            } else
            {
                printf("Client disconnected\n");
            }
            break;
        } else
        {
            buffer[len] = '\0';  // 确保字符串结束
            printf("info:%s len:%zd\n", buffer, len);
        }
    }
    close(clientfd);
    return nullptr;
}

int TcpServer::accept_epoll()
{
    struct epoll_event events[EPOLL_SIZE] = {0};
    memset(events, 0, EPOLL_SIZE);

    while (1)
    {
        //-1:无事件不询问 0:一直询问
        /*
         * @return nready 发生事件个数
         * @param events 储存发生事件的套接字
         */
        int nready = epoll_wait(epfd_, events, EPOLL_SIZE, 5);
        if (nready == -1) //无事件发生
        {
            continue;
        }
        for (int i = 0; i < nready; i++)
        {
            int sockfd = isListenFd(events[i].data.fd);
            if (sockfd)
            {
                struct sockaddr_in clientaddr{};
                socklen_t socklen = sizeof(struct sockaddr);
                memset(&clientaddr, 0, sizeof(struct sockaddr_in));

                int clientfd = ::accept(sockfd, (struct sockaddr *) &clientaddr, &socklen);

                ev_.events = EPOLLIN | EPOLLET;
                ev_.data.fd = clientfd;

                epoll_ctl(epfd_, EPOLL_CTL_ADD, clientfd, &ev_);
            } else
            {
                int clientfd = events[i].data.fd;
                char buffer[1024];
                ssize_t len = recv(clientfd, buffer, sizeof(buffer), 0);
                if (len <= 0)
                {
                    if (len < 0)
                    {
                        perror("recv error");
                    } else
                    {
                        printf("Client disconnected\n");
                    }
                    ev_.events = EPOLLIN;
                    ev_.data.fd = clientfd;
                    epoll_ctl(epfd_, EPOLL_CTL_DEL, clientfd, &ev_);
                    close(clientfd);  // 修复：关闭客户端socket
                } else
                {
                    buffer[len] = '\0';  // 确保字符串结束
                    printf("info:%s len:%zd\n", buffer, len);
                }
            }
        }
    }

}

int TcpServer::isListenFd(int fd)
{
    for (int i = 0; i < maxPort_; i++)
    {
        if (fd == sockfds_[i])
        {
            return fd;
        }
    }
    return 0;
}

int TcpServer::accept_select()
{
    fd_set rfds;
    FD_ZERO(&rfds);
    int maxfd = -1;
    for (int i = 0; i < maxPort_; i++)
    {
        FD_SET(sockfds_[i], &rfds);
        if (sockfds_[i] > maxfd)
        {
            maxfd = sockfds_[i];
        }
    }

    while (1)
    {
        fd_set newrfds;
        FD_ZERO(&newrfds);
        for (int fd = 0; fd <= maxfd; fd++)
        {
            if (FD_ISSET(fd, &rfds))
            {
                FD_SET(fd, &newrfds);
            }
        }

        int nready = select(maxfd + 1, &newrfds, nullptr, nullptr, nullptr);
        if (nready <= 0)
        {
            continue;
        }

        for (int fd = 0; fd <= maxfd; fd++)
        {
            if (!FD_ISSET(fd, &newrfds)) continue;

            int listenFd = isListenFd(fd);
            if (listenFd)
            {
                // 这是监听socket，接受新连接
                struct sockaddr_in clientaddr{};
                socklen_t socklen = sizeof(struct sockaddr_in);
                int clientfd = ::accept(listenFd, (struct sockaddr *) &clientaddr, &socklen);
                if (clientfd < 0)
                {
                    continue;
                }
                // 设置非阻塞
                fcntl(clientfd, F_SETFL, fcntl(clientfd, F_GETFL) | O_NONBLOCK);

                FD_SET(clientfd, &rfds);
                if (clientfd > maxfd)
                {
                    maxfd = clientfd;
                }
            } else
            {
                // 这是客户端socket，接收数据
                char buf[4096];
                ssize_t n = recv(fd, buf, sizeof(buf), 0);

                if (n <= 0)
                {
                    // 连接关闭或错误
                    if (n == 0)
                    {
                        printf("Client fd=%d disconnected\n", fd);
                    } else
                    {
                        // 检查是否是EAGAIN错误（非阻塞模式下暂时无数据）
                        if (errno == EAGAIN || errno == EWOULDBLOCK)
                        {
                            // 暂时无数据，继续等待
                            continue;
                        } else
                        {
                            perror("recv error");
                        }
                    }
                    close(fd);
                    FD_CLR(fd, &rfds);  // 从监听集合移除

                    // 更新 maxfd
                    if (fd == maxfd)
                    {
                        maxfd = -1;
                        for (int i = 0; i <= 1024; i++)
                        {
                            if (FD_ISSET(i, &rfds) && i > maxfd)
                            {
                                maxfd = i;
                            }
                        }
                    }
                } else
                {
                    // 处理收到的数据（示例：原样回传）
                    buf[n] = '\0';
                    printf("Recv from fd=%d: %s\n", fd, buf);
                    send(fd, buf, n, 0);
                }
            }
        }
    }
}

int TcpServer::accept_poll()
{
    struct pollfd fds[1024] = {0};
    int maxfd = -1;
    int nfds = 0;  // 添加：跟踪有效的fd数量

    // 初始化监听socket
    for (int i = 0; i < maxPort_; i++)
    {
        fds[i].fd = sockfds_[i];
        fds[i].events = POLLIN;
        if (sockfds_[i] > maxfd) maxfd = sockfds_[i];
        nfds = i + 1;
    }

    while (1)
    {
        int nready = ::poll(fds, nfds, -1);
        if (nready <= 0)
        {
            continue;
        }

        for (int i = 0; i < nfds; i++)
        {
            if (!(fds[i].revents & POLLIN)) continue;

            int fd = fds[i].fd;
            if (isListenFd(fd))
            {
                struct sockaddr_in clientaddr{};
                socklen_t socklen = sizeof(struct sockaddr_in);
                int clientfd = ::accept(fd, (struct sockaddr *) &clientaddr, &socklen);
                if (clientfd < 0)
                {
                    continue;
                }

                fcntl(clientfd, F_SETFL, fcntl(clientfd, F_GETFL) | O_NONBLOCK);

                fds[nfds].fd = clientfd;
                fds[nfds].events = POLLIN;
                nfds++;

                if (clientfd > maxfd) maxfd = clientfd;
            } else
            {
                char buf[4096];
                ssize_t n = recv(fd, buf, sizeof(buf), 0);

                if (n <= 0)
                {
                    if (n == 0)
                    {
                        printf("Client fd=%d disconnected\n", fd);
                    } else
                    {
                        if (errno == EAGAIN || errno == EWOULDBLOCK)
                        {
                            continue;
                        } else
                        {
                            perror("recv error");
                        }
                    }
                    close(fd);

                    fds[i].fd = -1;
                    fds[i].events = 0;

                    for (int j = i; j < nfds - 1; j++)
                    {
                        fds[j] = fds[j + 1];
                    }
                    nfds--;
                    i--;

                    if (fd == maxfd)
                    {
                        maxfd = -1;
                        for (int j = 0; j < nfds; j++)
                        {
                            if (fds[j].fd > maxfd) maxfd = fds[j].fd;
                        }
                    }
                } else
                {
                    buf[n] = '\0';
                    printf("Recv from fd=%d: %s\n", fd, buf);
                    send(fd, buf, n, 0);
                }
            }
        }
    }
}

int TcpServer::accept_reactor()
{
    struct epoll_event events[EPOLL_SIZE] = {0};
    memset(events, 0, EPOLL_SIZE);
    while (1)
    {
        int nready = epoll_wait(epfd_, events, EPOLL_SIZE, -1);

        for (int i = 0; i < nready; i++)
        {
            int connfd = events[i].data.fd;
            if (events[i].events & EPOLLIN)
            {
                conn_list[connfd].r_action.recv_callback(connfd);
            }
            if (events[i].events & EPOLLOUT)
            {
                conn_list[connfd].send_callback(connfd);
            }
        }
    }
}

int TcpServer::set_event(int fd, int event, int flag)
{
    if (flag)
    {
        ev_.events = event;
        ev_.data.fd = fd;
        epoll_ctl(epfd_, EPOLL_CTL_ADD, fd, &ev_);
    } else
    {
        ev_.events = event;
        ev_.data.fd = fd;
        epoll_ctl(epfd_, EPOLL_CTL_MOD, fd, &ev_);
    }

    return 1;
}

int TcpServer::accept_cb(int fd)
{
    struct sockaddr_in clientaddr{};
    memset(&clientaddr, 0, sizeof(sockaddr_in));
    socklen_t clientlen = sizeof(clientaddr);
    int clientfd = ::accept(fd, (struct sockaddr *) &clientaddr, &clientlen);

    if (clientfd < 0)
    {
        std::cout << "accept error" << std::endl;
        return -1;
    }

    // 设置非阻塞模式
    int flags = fcntl(clientfd, F_GETFL, 0);
    fcntl(clientfd, F_SETFL, flags | O_NONBLOCK);

    conn_list[clientfd].fd = clientfd;
    conn_list[clientfd].r_action.recv_callback = std::bind(&TcpServer::recv_cb, this, std::placeholders::_1);
    conn_list[clientfd].send_callback = std::bind(&TcpServer::send_cb, this, std::placeholders::_1);

    memset(conn_list[clientfd].rbuffer, 0, 1024);
    conn_list[clientfd].rlength = 0;

    memset(conn_list[clientfd].wbuffer, 0, 1024);
    conn_list[clientfd].wlength = 0;

    set_event(clientfd, EPOLLIN, 1);
    return clientfd;
}

int TcpServer::recv_cb(int fd)
{
    int count = recv(fd, conn_list[fd].rbuffer, 1024, 0);
    if (count == 0)
    {
        std::cout << "disconnection" << std::endl;
        close(fd);
        epoll_ctl(epfd_, EPOLL_CTL_DEL, fd, nullptr);
        return 0;
    }
    conn_list[fd].rlength = count;

//    memcpy(conn_list[fd].wbuffer, conn_list[fd].rbuffer, 1024);
//    conn_list[fd].wlength = count;
//
//    printf("RECV : %s", conn_list[fd].rbuffer);
//    memset(conn_list[fd].rbuffer, 0, 1024);
//    conn_list[fd].rlength = 0;
    //set_event(fd, EPOLLOUT, 0);
    return count;
}

int TcpServer::send_cb(int fd)
{
    int count = send(fd, conn_list[fd].wbuffer, conn_list[fd].wlength, 0);
    memset(conn_list[fd].wbuffer, 0, 1024);
    conn_list[fd].wlength = 0;
    set_event(fd, EPOLLIN, 0);
    return count;
}
